package com.jcfk.system.controller;

import cn.hutool.core.util.StrUtil;
import com.jcfk.common.business.log.model.OperateLog;
import com.jcfk.common.business.log.service.OperateLogger;
import com.jcfk.common.cache.redis.service.RedisStringService;
import com.jcfk.common.core.context.SpringContextUtils;
import com.jcfk.common.security.annotation.AllowAnonymous;
import com.jcfk.common.security.service.TokenService;
import com.jcfk.common.security.utils.SecurityUtils;
import com.jcfk.common.web.domain.LoginInfo;
import com.jcfk.common.web.domain.RetResult;
import com.jcfk.common.web.domain.TokenInfo;
import com.jcfk.common.web.utils.ServletUtils;
import com.jcfk.system.domain.dto.PersonLoginDTO;
import com.jcfk.system.domain.dto.PersonLoginRequest;
import com.jcfk.system.service.PersonLoginService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.TimeUnit;

/**
 * 人员登录 api
 *
 * @author 李炳海
 */
@Api(tags = "personLogin", description = "人员登录")
@RestController
@RequestMapping("/personLogin")
public class PersonLoginController {

    private static TokenService tokenService= SpringContextUtils.getBean(TokenService.class);

    /**
     * 操作日志工具
     */
    @Autowired
    private OperateLogger operateLogger;

    /**
     * 人员登录服务
     */
    @Autowired
    private PersonLoginService personLoginService;

    /**
     * 缓存服务
     */
    @Autowired
    private RedisStringService redisStringService;


    /**
     * 错误登录次数关键字
     */
    private String loginErrorCountKey = "login:loginErrorCount";

    /**
     * 扫描员工号登录
     *
     * @param loginParameter 登录参数
     * @return QueryResultModel
     */
    @PostMapping("scanIdLogin")
    @AllowAnonymous
    public RetResult<TokenInfo> scanIdLogin(@RequestBody PersonLoginRequest loginParameter) {

        RetResult<TokenInfo> login = new RetResult<>();

        // 登录
        login = personLoginService.login(loginParameter);


        //#region 防频繁登录机制

        HttpServletRequest request = ServletUtils.getRequest();
        String clientIp;
        if (request != null) {
            clientIp = ServletUtils.getClientRequestIp(request);
        } else {
            clientIp = "127.0.0.1";
        }

        Integer loginErrorCount = 0;
        loginErrorCount = redisStringService.getValue(loginErrorCountKey + ":" + clientIp, Integer.class);
        if (loginErrorCount == null) {
            loginErrorCount = 0;
        }

        //#endregion

        if (!login.getCode().equals(RetResult.SUCCESS)) {
            loginErrorCount++;
            redisStringService.setValue(loginErrorCountKey + ":" + clientIp, loginErrorCount, 1L, TimeUnit.MINUTES);
            if (loginErrorCount >= 3) {
                operateLogger.error(this.getClass(),
                        new OperateLog("用户登录", "登录", "/login/doLogin", loginParameter, RetResult.fail(429, "登录过于频繁，请1分钟后再试")));
                return RetResult.fail(429, "登录过于频繁，请1分钟后再试");
            }
            return RetResult.fail(login.getData(), login.getMessage());
        }
        loginErrorCount = 0;
        redisStringService.setValue(loginErrorCountKey + ":" + clientIp, loginErrorCount, 1L, TimeUnit.MINUTES);

        operateLogger.info(this.getClass(),
                new OperateLog("用户登录", "登录", "/login/doLogin", loginParameter, RetResult.ok(login.getData(), "登录成功")));

        return RetResult.ok(login.getData(), "登录成功");
    }

    /**
     * 获取登录信息
     *
     * @param tokenInfo
     * @return RetResult
     */
    @AllowAnonymous
    @PostMapping("getPersonLoginInfo")
    public RetResult<PersonLoginDTO> getPersonLoginInfo(@RequestBody(required = false) TokenInfo tokenInfo) throws InvocationTargetException, IllegalAccessException {
        PersonLoginDTO personLoginDTO=new PersonLoginDTO();
        LoginInfo loginInfo=tokenService.getLoginInfo();

        personLoginDTO.setUserId(loginInfo.getUserId());
        personLoginDTO.setUserName(loginInfo.getUserName());
        if(loginInfo.getParameters()!=null){
            personLoginDTO.setMemberEmpNo(loginInfo.getParameters().get("empNo"));
            personLoginDTO.setWorkCenterId(loginInfo.getParameters().get("workCenterId"));
            personLoginDTO.setWorkCenterCode(loginInfo.getParameters().get("workCenterCode"));
            personLoginDTO.setWorkCenterName(loginInfo.getParameters().get("workCenterName"));
            personLoginDTO.setCrewId(loginInfo.getParameters().get("crewId"));
            personLoginDTO.setCrewName(loginInfo.getParameters().get("crewName"));
        }
        return RetResult.ok(personLoginDTO);
    }
}
